package com.igame.Service.impl;


import com.fasterxml.jackson.databind.ObjectMapper;
import com.igame.Service.PrivateMessagesService;

import com.igame.Service.UserService;
import com.igame.common.Result;
import com.igame.constant.CommentConstant;
import com.igame.dto.ContactDto;
import com.igame.dto.MessageDto;
import com.igame.entity.PrivateMessages;
import com.igame.mapper.PrivateMessagesMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;


@Service
public class PrivateMessagesImpl implements PrivateMessagesService{

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private UserService userService;

    @Autowired
    private PrivateMessagesMapper privateMessagesMapper;

    @Autowired
    private ObjectMapper objectMapper; // JSON 解析工具

    private static final String CACHE_KEY_PREFIX = "private_message:"; // Redis 缓存键的前缀
    @Override
    public Result<Boolean> initiateContact(ContactDto contactDto) {
        // 检查是否用户试图与自己联系
        if (Objects.equals(contactDto.getSendId(), contactDto.getReceiverId())) {
            return Result.error("不能与自己联系");
        }
        // 创建两个用户的联系人集合键
        String userContactsKey = "user_contacts:" + contactDto.getSendId();
        String receiverContactsKey = "user_contacts:" + contactDto.getReceiverId();
        // 添加联系对象到集合中
        stringRedisTemplate.opsForSet().add(userContactsKey, contactDto.getReceiverId().toString());
        stringRedisTemplate.opsForSet().add(receiverContactsKey, contactDto.getSendId().toString());
        // 返回成功状态
        return Result.success(true);
    }

    @Override
    public Result<Set<String>> getAllContacts(Integer userId) {
        // 获取当前登录用户的联系人
        String adminContactsKey = "user_contacts:"+userId;
        //根据用户命获取联系过的人的列表
        Set<String> contacts = stringRedisTemplate.opsForSet().members(adminContactsKey);
        return Result.success(contacts);
    }

    @Override
    @Transactional
    public Result sendMessage(MessageDto messageDto) {
        try {
            if (messageDto.getMessage() == null || messageDto.getMessage().isEmpty()) {
                return Result.error("请输入内容!");
            }
            // 创建 PrivateMessages 对象
            PrivateMessages privateMessages = new PrivateMessages();
            privateMessages.setSenderId(messageDto.getSendUser());
            privateMessages.setReceiverId(messageDto.getReceiver());
            privateMessages.setMessage(messageDto.getMessage());
            privateMessages.setTimestamp(LocalDateTime.now());
            privateMessages.setIsNew(CommentConstant.isNew);

            // 转换消息为 JSON 字符串
            String messageJson = objectMapper.writeValueAsString(privateMessages);

            // 存储到 Redis 列表中
            String senderKey = CACHE_KEY_PREFIX + privateMessages.getSenderId();
            String receiverKey = CACHE_KEY_PREFIX + privateMessages.getReceiverId();

            stringRedisTemplate.opsForList().rightPush(senderKey, messageJson);
            stringRedisTemplate.opsForList().rightPush(receiverKey, messageJson);

            return Result.success();
        } catch (Exception e) {
            return Result.error("发送消息失败: " + e.getMessage());
        }
    }

    @Override
    public Result<List<PrivateMessages>> getMessagesBetweenUsers(Integer senderId, Integer receiverId) {
        try {
            // 从 Redis 中获取发送者和接收者的消息
            String senderKey = CACHE_KEY_PREFIX + senderId;
            String receiverKey = CACHE_KEY_PREFIX + receiverId;

            List<String> senderMessagesJsonList = stringRedisTemplate.opsForList().range(senderKey, 0, -1);
            List<String> receiverMessagesJsonList = stringRedisTemplate.opsForList().range(receiverKey, 0, -1);

            // 使用 Set 以避免重复消息
            Set<PrivateMessages> messagesSet = new HashSet<>();

            // 解析消息并添加到 Set 中
            if (senderMessagesJsonList != null) {
                for (String messageJson : senderMessagesJsonList) {
                    PrivateMessages message = objectMapper.readValue(messageJson, PrivateMessages.class);
                    // 仅添加发送者是目标 senderId 且接收者是目标 receiverId 的消息
                    if (message.getSenderId().equals(senderId) && message.getReceiverId().equals(receiverId)) {
                        messagesSet.add(message);
                    }
                }
            }

            if (receiverMessagesJsonList != null) {
                for (String messageJson : receiverMessagesJsonList) {
                    PrivateMessages message = objectMapper.readValue(messageJson, PrivateMessages.class);
                    // 仅添加发送者是目标 receiverId 且接收者是目标 senderId 的消息
                    if (message.getSenderId().equals(receiverId) && message.getReceiverId().equals(senderId)) {
                        messagesSet.add(message);
                    }
                }
            }

            // 将 Set 转换为 List 以进行排序
            List<PrivateMessages> messages = new ArrayList<>(messagesSet);

            // 返回按照时间顺序排序的消息列表
            messages.sort(Comparator.comparing(PrivateMessages::getTimestamp));
            return Result.success(messages);
        } catch (Exception e) {
            return Result.error("获取消息失败: " + e.getMessage());
        }
    }

    @Override
    public Integer getReceiverId(String receiverName) {
        return userService.getIdByName(receiverName.replace("\"", ""));
    }

    @Override
    public Result<Integer> getReadMessagesCountForReceiver(Integer loginId) {
        try {
            if (loginId!=0){
            // 从 Redis 中获取接收者的消息
            String receiverKey = CACHE_KEY_PREFIX + loginId;
            List<String> receiverMessagesJsonList = stringRedisTemplate.opsForList().range(receiverKey, 0, -1);
            // 计算符合条件的消息数量
            int count = 0;
            // 解析消息并统计
            if (receiverMessagesJsonList != null) {
                for (String messageJson : receiverMessagesJsonList) {
                    PrivateMessages message = objectMapper.readValue(messageJson, PrivateMessages.class);
                    // 仅统计接收者是目标 receiverId 且消息未读 (isNew=0) 的消息
                    if (message.getReceiverId().equals(loginId) && message.getIsNew().equals(0)) {
                        count++;
                    }
                }
            }
            // 返回结果
            return Result.success(count);
            }else {
                return Result.success(0);
            }
        } catch (Exception e) {
            return Result.error("获取已读消息数量失败: " + e.getMessage());
        }
    }

    @Override
    public void updateMessageStatusForReceiver(Integer loginId,Integer receiverId) {
        try {
            String receiverKey = CACHE_KEY_PREFIX + loginId;
            List<String> receiverMessagesJsonList = stringRedisTemplate.opsForList().range(receiverKey, 0, -1);
            if (receiverMessagesJsonList != null) {
                for (int i = 0; i < receiverMessagesJsonList.size(); i++) {
                    String messageJson = receiverMessagesJsonList.get(i);
                    PrivateMessages message = objectMapper.readValue(messageJson, PrivateMessages.class);
                    // 检查消息是否满足更新条件
                    if (message.getReceiverId().equals(loginId) && message.getSenderId().equals(receiverId) && message.getIsNew().equals(0)) {
                        // 更新消息状态
                        System.out.println(2);
                        message.setIsNew(CommentConstant.NotNew);
                        // 将更新后的消息对象转换为 JSON
                        String updatedMessageJson = objectMapper.writeValueAsString(message);
                        // 更新 Redis 中的消息
                        stringRedisTemplate.opsForList().set(receiverKey, i, updatedMessageJson);
                    }
                }
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    @Override
    public Result<Boolean> deleteContact(Integer loginId, Integer ContactId) {

        // 定义当前用户和联系人用户的集合键
        String userContactsKey = "user_contacts:" + loginId;
        String contactUserKey = "user_contacts:" + ContactId;

        // 从当前用户的联系人集合中删除联系人
        Long removedFromUser = stringRedisTemplate.opsForSet().remove(userContactsKey, ContactId.toString());

        // 从联系人用户的联系人集合中删除当前用户
        Long removedFromContactUser = stringRedisTemplate.opsForSet().remove(contactUserKey, loginId.toString());

        // 检查是否成功删除了联系人
        boolean success = (removedFromUser > 0) || (removedFromContactUser > 0);

        // 返回成功状态
        if (success) {
            return Result.success();
        } else {
            return Result.error("删除联系人失败");
        }

    }


    // 从 Redis 缓存中持久化消息到数据库
    @Scheduled(cron = "0 0 0 * * ?") // 每天0点执行
    public void persistMessagesFromCache() {
        // 获取昨天的日期
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime startOfDay = now.toLocalDate().atStartOfDay().minusDays(1);
        LocalDateTime endOfDay = startOfDay.plusDays(1);

        // 查找所有符合时间范围的消息
        Set<String> keys = stringRedisTemplate.keys(CACHE_KEY_PREFIX + "*");
        if (keys != null) {
            for (String key : keys) {
                String messageStr = stringRedisTemplate.opsForValue().get(key);
                if (messageStr != null) {
                    try {
                        PrivateMessages privateMessages = parseMessage(messageStr);
                        // 判断消息时间是否在前一天的范围内
                        if (privateMessages.getTimestamp().isAfter(startOfDay) && privateMessages.getTimestamp().isBefore(endOfDay)) {
                            privateMessagesMapper.insertPMessage(privateMessages);
                            stringRedisTemplate.delete(key);
                        }
                    } catch (Exception e) {
                        // 记录异常日志
                        System.err.println("持久化消息失败: " + e.getMessage());
                    }
                }
            }
        }
    }

    // 解析消息字符串为 PrivateMessages 对象
    private PrivateMessages parseMessage(String messageStr) {
        try {
            return objectMapper.readValue(messageStr, PrivateMessages.class);
        } catch (Exception e) {
            throw new RuntimeException("解析消息失败: " + e.getMessage(), e);
        }
    }
}
